package rolesystem.middle.GUI;

import java.awt.Button;
import java.awt.Choice;
import java.awt.Label;
import java.awt.Panel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.util.EventListener;
import java.util.Vector;

import javax.swing.JSlider;
import javax.swing.JTextField;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import rolesystem.agentlogic.managers.MovementManager;
import rolesystem.agentlogic.parameters.ConfigurationParameters;
import rolesystem.jade.agents.carry.carrier.CarrierSL;
import rolesystem.middle.managers.BooleanManager;
import rolesystem.middle.managers.CounterManager;
import rolesystem.middle.managers.EnvironmentManager;
import rolesystem.middle.parameters.DefaultParametersGUI;

public class GuiControls extends Panel implements EventListener, WindowListener 
{
	private static final long serialVersionUID = 5154526512960757099L;
	
	private Label speedLabel;
	private Label foodSliderLabel;
	private Label obstaclesSliderLabel;
	private Label killLabel;
	
	private Vector<EventListener> listeners;
	
	private Button startstopButton;
	private Button resetButton;
	private Button killButton;
	private Choice speedChoice;
	private JSlider sliderFood;  
	private JSlider sliderObstacles;
	private JTextField agentField;
	
	private int agentNumber;
	
	public GuiControls() 
	{
		listeners = new Vector<EventListener>();
		
		// pulldown menu with speeds
		speedChoice = new Choice();
		
		// add speeds
		speedChoice.addItem(DefaultParametersGUI.SLOW);
		speedChoice.addItem(DefaultParametersGUI.FAST);
		speedChoice.addItem(DefaultParametersGUI.HYPER);
		
		// when item is selected
		speedChoice.addItemListener(
				new ItemListener() {
					public void itemStateChanged(ItemEvent e) {
						String arg = (String) e.getItem();
						if (DefaultParametersGUI.SLOW.equals(arg)) // slow
							speedChanged(800);
						else if (DefaultParametersGUI.FAST.equals(arg)) // fast
							speedChanged(400);
						else if (DefaultParametersGUI.HYPER.equals(arg)) // hyperspeed
							speedChanged(200);
					}
				}
				);
		
		speedChoice.select(DefaultParametersGUI.FAST);
		
		// label (speed)
		speedLabel = new Label(DefaultParametersGUI.speedLabelText);
		
		killLabel = new Label(DefaultParametersGUI.killLabelText);
		
		// start and stop buttom
		startstopButton = new Button(DefaultParametersGUI.startLabelText);
		
		// when start/stop button is clicked
		startstopButton.addActionListener(
				new ActionListener() {
					public void actionPerformed(ActionEvent e) {
						startStopButtonClicked();
					}
				}
				);
		
		killButton= new Button(DefaultParametersGUI.killButtonLabelText);
		
		killButton.addActionListener(
				new ActionListener() {
					public void actionPerformed(ActionEvent e) {
						killButtonClicked();
					}
				}
				);
		
		// next generation button
		resetButton = new Button(DefaultParametersGUI.resetLabelText);
		
		// when next button is clicked
		resetButton.addActionListener(
				new ActionListener() {
					public void actionPerformed(ActionEvent e) {
						resetButtonClicked();
					}
				}
				);
		
		obstaclesSliderLabel= new Label(DefaultParametersGUI.obstaclesSliderLabelText);
		sliderObstacles = new JSlider(JSlider.HORIZONTAL, 0, 30, 15);
		
		sliderObstacles.addChangeListener( new ChangeListener() 
		{
			public void stateChanged(ChangeEvent e)  
			{
				SliderObstaclesState(e);
			}
		});
		
		
		agentField= new JTextField(DefaultParametersGUI.agentFieldText,DefaultParametersGUI.AGENT_FIELD_COLUMNS);
		
		agentField.addActionListener(new ActionListener() 
		{
			public void actionPerformed(ActionEvent evt) {
			    String text = agentField.getText();
			    int nAcquired;
			    try
				{
			    	nAcquired=Integer.parseInt( text );
				} catch (NumberFormatException e)
				{
					nAcquired=-1;
				}
			    agentNumber=nAcquired;
			}
		});
		
		//Turn on labels at major tick marks.

		
		sliderObstacles.setMajorTickSpacing(DefaultParametersGUI.MAJOR_TICK_SPACING);
		sliderObstacles.setMinorTickSpacing(DefaultParametersGUI.MINOR_TICK_SPACING);
		sliderObstacles.setPaintTicks(DefaultParametersGUI.PAINT_TICKS);
		sliderObstacles.setPaintLabels(DefaultParametersGUI.PAINT_LABELS);
		
		this.setLayout(null);
		
		startstopButton.setSize(DefaultParametersGUI.SIZE_STARTSTOPBUTTON);
		startstopButton.setLocation(DefaultParametersGUI.POS_STARTSTOPBUTTON);
		
		resetButton.setSize(DefaultParametersGUI.SIZE_RESETBUTTON);
		resetButton.setLocation(DefaultParametersGUI.POS_RESETBUTTON);
		
		speedLabel.setSize(DefaultParametersGUI.SIZE_SPEEDLABEL);
		speedLabel.setLocation(DefaultParametersGUI.POS_SPEEDLABEL);
		
		speedChoice.setSize(DefaultParametersGUI.SIZE_SPEEDCHOICE);
		speedChoice.setLocation(DefaultParametersGUI.POS_SPEEDCHOICE);
		
		obstaclesSliderLabel.setSize(DefaultParametersGUI.SIZE_OBSTACLESSLIDERLABEL);
		obstaclesSliderLabel.setLocation(DefaultParametersGUI.POS_OBSTACLESSLIDERLABEL);
		
		sliderObstacles.setSize(DefaultParametersGUI.SIZE_SLIDEROBSTACLES);
		sliderObstacles.setLocation(DefaultParametersGUI.POS_SLIDEROBSTACLES);
		
		agentField.setSize(DefaultParametersGUI.SIZE_AGENTFIELD);
		agentField.setLocation(DefaultParametersGUI.POS_AGENTFIELD);
		
		killButton.setSize(DefaultParametersGUI.SIZE_KILLBUTTON);
		killButton.setLocation(DefaultParametersGUI.POS_KILLBUTTON);
		
		killLabel.setSize(DefaultParametersGUI.SIZE_KILLLABEL);
		killLabel.setLocation(DefaultParametersGUI.POS_KILLLABEL);
		
		addGameOfLifeControlsListener(this);
		
		if(DefaultParametersGUI.FOOD_CONTROLS)
		{	
			//Create the labels       
			foodSliderLabel= new Label(DefaultParametersGUI.foodSliderLabelText);
			
			//Create the slider.
			sliderFood = new JSlider(JSlider.HORIZONTAL, 0, 50, 15);
			
			sliderFood.setMajorTickSpacing(DefaultParametersGUI.MAJOR_TICK_SPACING);
			sliderFood.setMinorTickSpacing(DefaultParametersGUI.MINOR_TICK_SPACING);
			sliderFood.setPaintTicks(DefaultParametersGUI.PAINT_TICKS);
			sliderFood.setPaintLabels(DefaultParametersGUI.PAINT_LABELS);
			
			sliderFood.addChangeListener( new ChangeListener() 
			{
				public void stateChanged(ChangeEvent e)  
				{
					SliderFoodState(e);
				}
			});
			
			foodSliderLabel.setSize(DefaultParametersGUI.SIZE_FOODSLIDERLABEL);
			foodSliderLabel.setLocation(DefaultParametersGUI.POS_FOODSLIDERLABEL);
			
			sliderFood.setSize(DefaultParametersGUI.SIZE_SLIDERFOOD);
			sliderFood.setLocation(DefaultParametersGUI.POS_SLIDERFOOD);
			
			this.add(foodSliderLabel);
			this.add(sliderFood);
		}
		
		// create panel with controls
		this.add(startstopButton);
		this.add(resetButton);
		this.add(speedLabel);
		this.add(speedChoice);
		this.add(obstaclesSliderLabel);
		this.add(sliderObstacles);
		this.add(killButton);
		this.add(killLabel);
		this.add(agentField);
		
		this.validate();
	}
	
	public void addGameOfLifeControlsListener( EventListener listener ) 
	{
		listeners.addElement(listener);
	}
	
	
	public void SliderFoodState(ChangeEvent e) 
	{
		JSlider source = (JSlider)e.getSource();
		if (!source.getValueIsAdjusting()) 
		{
			int food = (int)source.getValue();
			EnvironmentManager.weightNumbers[0]=food;
		}
	}
	
	public void SliderObstaclesState(ChangeEvent e) 
	{
		JSlider source = (JSlider)e.getSource();
		if (!source.getValueIsAdjusting()) 
		{
			int obstacles = (int)source.getValue();
			EnvironmentManager.OBSTACLES_NUMBER=obstacles;
		}
	}
	
	/**
	 * Start-button is activated.
	 */
	 public void start() 
	{
		startstopButton.setLabel(DefaultParametersGUI.stopLabelText);
	}
	 
	 /**
	  * Stop-button is activated.
	  */
	 public void stop() 
	 {
		 startstopButton.setLabel(DefaultParametersGUI.startLabelText);
	 }
	 
	 /**
	  * Called when the start/stop-button is clicked.
	  */
	 public void startStopButtonClicked() 
	 {
		 if(startstopButton.getLabel().equals(DefaultParametersGUI.startLabelText))
		 {
			 startstopButton.setLabel(DefaultParametersGUI.stopLabelText);
			 BooleanManager.set(ConfigurationParameters.STOP_BOOL,false);
			 
			 resetButton.setEnabled(false);
		 }
		 else
		 {
			 startstopButton.setLabel(DefaultParametersGUI.startLabelText);
			 BooleanManager.set(ConfigurationParameters.STOP_BOOL,true);
			 
			 resetButton.setEnabled(true);
		 }	
	 }
	 
	 /**
	  * Called when the agent kill button is clicked.
	  */
	 public void killButtonClicked() 
	 {
		 String text = agentField.getText();
		 int nAcquired;
		 try
		 {
			 nAcquired=Integer.parseInt( text );
		 } catch (NumberFormatException e)
		 {
			 nAcquired=-1;
		 }
		 agentNumber=nAcquired;
		 
		 if(this.agentNumber>0 && this.agentNumber<CounterManager.get(ConfigurationParameters.ID_COUNTER)) 
			 BooleanManager.set(ConfigurationParameters.EXIT_AGENT_BASE_BOOL + String.valueOf(agentNumber),true); 
	 }
	 
	 /**
	  * Called when the reset button is clicked.
	  */
	 public void resetButtonClicked() 
	 {
		 BooleanManager.set(ConfigurationParameters.RESET_BOOL,true);
	 }
	 
	 /**
	  * Called when a new speed from the speed pull down is selected.
	  */
	 public void speedChanged(int speed) 
	 {
		 ConfigurationParameters.PAUSE=speed;
	 }
	 
	 public void windowClosing(WindowEvent e) {}
	 
	 public void windowClosed(WindowEvent e) 
	 {
		 BooleanManager.set(ConfigurationParameters.EXIT_BOOL,true);
	 }
	 
	 public void windowOpened(WindowEvent e) {}
	 
	 public void windowIconified(WindowEvent e) {}
	 
	 public void windowDeiconified(WindowEvent e) {}
	 
	 public void windowActivated(WindowEvent e) {}
	 
	 public void windowDeactivated(WindowEvent e) {}
	 
}
